#include <iostream>
#include <vector>
#include <memory>

class memorypool
{
public:
    memorypool(size_t blocksize)
    {
        _poolsize = blocksize;
        _memory = new char[_poolsize];
        _freelist = reinterpret_cast<Block *>(_memory); // 将内存块的首地址转换为Block类型的指针
        _freelist->size = _poolsize - sizeof(Block);
        _freelist->isfree = true;
        _freelist->next = nullptr;
    }
    ~memorypool()
    {
        delete[] _memory;
    }

    // 在分配时打印调试信息
    void *allocate(size_t size)
    {
        Block *prev = nullptr;
        Block *curr = _freelist;

        // 遍历空闲块链表，寻找合适的块
        while (curr != nullptr)
        {
            if (curr->isfree && curr->size >= size)
            {
                // 找到合适的块
                if (curr->size > size + sizeof(Block))
                {
                    // 如果块的大小大于所需大小，分割块
                    Block *newBlock = reinterpret_cast<Block *>(reinterpret_cast<char *>(curr) + sizeof(Block) + size);
                    newBlock->size = curr->size - size - sizeof(Block);
                    newBlock->isfree = true;
                    newBlock->next = curr->next;

                    curr->size = size;
                    curr->next = newBlock;
                }

                // 标记块为已使用
                curr->isfree = false;
                return reinterpret_cast<void *>(reinterpret_cast<char *>(curr) + sizeof(Block));
            }

            prev = curr;
            curr = curr->next;
        }

        // 没有找到合适的块，返回空指针
        return nullptr;
    }

    // 在释放时打印调试信息
    void deallocate(void *ptr)
    {
        if (ptr == nullptr)
            return;

        // 获取块的起始地址
        Block *block = reinterpret_cast<Block *>(reinterpret_cast<char *>(ptr) - sizeof(Block));
        block->isfree = true;
        std::cout << "Deallocating block at " << block << ", Size: " << block->size << "\n";

        // 合并相邻的空闲块
        Block *curr = _freelist;
        while (curr != nullptr)
        {
            // 如果当前块和下一个块都是空闲的，进行合并
            if (curr->isfree && curr->next != nullptr && curr->next->isfree)
            {
                // 合并当前块和下一个块
                curr->size += sizeof(Block) + curr->next->size;
                curr->next = curr->next->next;
            }
            else
            {
                curr = curr->next;
            }
        }
    }

    void printMemoryPool() const
    {
        Block *curr = _freelist;
        std::cout << "Memory Pool Status:\n";
        while (curr != nullptr)
        {
            std::cout << "Block at " << curr << ", Size: " << curr->size
                      << ", Free: " << (curr->isfree ? "Yes" : "No") << "\n";
            curr = curr->next;
        }
    }

private:
    struct Block
    {
        size_t size;
        bool isfree;
        Block *next;
    };

    size_t _poolsize;
    char *_memory;
    Block *_freelist;
};

int main()
{
    // 创建一个大小为1024字节的内存池
    memorypool pool(1024);

    // 分配内存
    void *ptr1 = pool.allocate(128);
    void *ptr2 = pool.allocate(256);
    void *ptr3 = pool.allocate(64);

    // 打印内存池状态
    pool.printMemoryPool();

    // 释放内存
    pool.deallocate(ptr2);
    pool.deallocate(ptr1);

    // 打印内存池状态
    pool.printMemoryPool();

    return 0;
}